use regex::Regex;
use std::env::{self, Args};
use std::fs;
use text_colorizer::*;

#[derive(Debug)]
struct Arguments {
    target: String,
    replacement: String,
    filename: String,
    output: String,
}
/*
1. 运行创建源文件: echo "hello,world" > test.txt
2. 运行程序: cargo run "world" "Rust" test.txt test-modified.txt
3. 查看目录下的新文件检查内容是否已经替换
*/
fn main() {
    let args = parse_args();
    print!("{:?}", args);

    // 读入文件的数据到变量内部
    let data = match fs::read_to_string(&args.filename) {
        Ok(v) => v,
        Err(e) => {
            eprintln!(
                "{} 读取文件时失败 '{}' : {:?}",
                "Error:".red().bold(),
                args.filename,
                e
            );
            std::process::exit(1);
        }
    };

    let replaced_data = match replace(&args.target, &args.replacement, &data) {
        Ok(v) => v,
        Err(e) => {
            eprintln!("{} 替换文本时失败: {:?}", "Error:".red().bold(), e);
            std::process::exit(1);
        }
    };

    // 将变量的数据写入文件
    match fs::write(&args.output, &replaced_data) {
        Ok(_) => {}
        Err(e) => {
            eprintln!(
                "{} 写入文件失败: '{}': {:?}",
                "Error:".red().bold(),
                args.output,
                e
            );
            std::process::exit(1);
        }
    };
}

fn print_usage() {
    eprintln!("{} - 可以快速替换字符串", "quickReplace".green());
    eprintln!("Usage: quickReplace <target> <replacement> <INPUT> <OUTPUT>");
}

fn parse_args() -> Arguments {
    let args: Vec<String> = env::args().skip(1).collect();

    if args.len() != 4 {
        print_usage();
        eprintln!(
            "{} 错误的参数数量: expected 4, got {}.",
            "Error: ".red().bold(),
            args.len()
        );
        std::process::exit(1);
    }

    Arguments {
        target: args[0].clone(),
        replacement: args[1].clone(),
        filename: args[2].clone(),
        output: args[3].clone(),
    }
}

fn replace(target: &str, replacement: &str, text: &str) -> Result<String, regex::Error> {
    let regex = Regex::new(target)?;
    Ok(regex.replace_all(text, replacement).to_string())
}
